/*
 进程和线程
   电脑每开启一个程序，就会开辟一个进程！
   线程就是一个进程中具体执行事情的，一个进程中可能会开辟一到多个线程！
     单线程：同时只能做一件事情，上一件处理完成，下一件事情才会开始！ =>同步编程
     多线程：同时可以处理多件事情 =>异步编程
   打开一个浏览器页面，就会创建一个进程！！在每一个页面中，需要处理很多事情，所以浏览器会分配多个线程，同时去进行处理！！=> “浏览器是多线程操作”
     GUI渲染线程：渲染和解析HTML/CSS代码的
     JS引擎线程：渲染和解析JS的
     HTTP网络线程：从服务器获取(或加载)相关的资源
     定时器监听线程：监听定时器是否到时间
     事件监听线程：监听事件是否被触发
     ...


 浏览器底层渲染机制：基于HTTP网络从服务器端获取到HTML代码后，到渲染出整个页面，中间所经历的事情！
   浏览器分配GUI渲染线程，自上而下逐行解析HTML代码！代码渲染过程中，遇到下述标签，是如何处理的？
   @1 <link href=""/>
     首先会开辟一个新的HTTP网络线程，去服务器加载相关的资源「浏览器对于开辟的HTTP线程有限制：大概5~7个」
     GUI渲染线程会继续向下解析！
     总结：link不会阻碍GUI的渲染、属于异步操作

   @2 <style></style>
     即便CSS代码已经存在于style中，但是GUI也不会立即渲染解析；需要等待所有CSS资源都获取到之后，按照事先编写的顺序，依次渲染解析CSS代码；只有这样才可以保障CSS的层叠优先级！！

   @3 <style> @import 'xxx.css'; </style>
     遇到@import，首先会开辟HTTP网络线程，去服务器获取相关资源，与此同时，GUI会暂停渲染；只有把资源获取到之后，GUI才会继续渲染！！
     总结：@import会阻碍GUI的渲染、属于同步操作

   @4 <img src=''/>
     和<link>操作相似，也是开辟新的HTTP线程去服务器获取资源，不会阻碍GUI渲染，属于异步操作！！

   @5 <script></script>
     如果设置了src，则需要开辟HTTP网络线程，去服务器获取相关的资源！
     没有设置src，则代码就在这，无需从服务器获取！！
     script会阻碍GUI的渲染：只有把js代码获取到，并且渲染解析完毕后，才让GUI继续渲染！！

     <script async></script>
     + 基于HTTP线程，获取资源的操作和GUI渲染是同时进行的~
     + 但是当JS资源获取大之后，会立即阻碍GUI，开始把获取的js执行！
     + 只有当js执行完，GUI才会继续向下渲染！
     + 获取资源和GUI是同时的「异步操作」；但是哪个js资源先获取到，就先把谁渲染解析了「和js导入的顺序无关」

     <script defer></script>
     + 和<link>非常相似，不会阻碍GUI渲染
     + 基于HTTP获取资源 和 基于JS引擎渲染解析JS，都不会阻碍GUI渲染
     + 等待所有JS资源获取到之后，按照之前编写的顺序(加defer)逐一渲染！

//====================
  浏览器渲染步骤
    @1 创建DOM数{DOM TREE}：描述节点之间的关系
      第一次渲染解析，先不处理CSS样式，只处理DOM结构！
      触发JS中的 DOMContentLoaded 事件！

    @2 创建CSSOM树{CSSOM TREE}：描述节点的样式
      当获取到CSS资源后，GUI开始渲染解析CSS，创建出CSSOM树

    @3 RENDER TREE渲染树{RENDER TREE}
      把DOM TREE和CSSOM TREE合并在一起，创建出RENDER TREE

    @4 Layout：布局排版「回流/重排」
      根据当前视口大小，计算出每个节点在视口中的位置、大小等

    @5 分层
      规划有哪些层(文档流)，以及层上每个节点的具体绘制规则！

    @6 Painting：绘制「重绘」
      按照之前规划好的规则，一层层进行绘制！！

//====================
  前端性能优化方案
   @1 因为HTTP网络线程有并发上限，所以尽可能减少HTTP网络请求
     + CSS合并为一个、JS合并为一个
     + 静态资源图片做“雪碧图”
     + CSS代码“较少”的情况下，可以使用内嵌式「尤其是移动端开发」

   @2 加快 DOM TREE 的构建
     + 不要阻碍GUI的渲染
       + 尽可能不使用 @import 导入式
       + <script>尽可能放在页面的底部、或者设置async/defer
     + 标签语义化、减少层级嵌套
       + 可以加快DOM TREE的构建
       + 也有利于SEO搜索引擎优化

   @3 加快 CSSOM TREE 的构建
     + 减少CSS选择器前缀的层级嵌套

   @4 减少对DOM的操作「原因：操作DOM非常消耗性能」
     诞生一系列框架：Vue、React、Angular...{放弃直接操作DOM，让开发者只需要操作数据，而框架内部实现了对DOM的操作和渲染}
     操作DOM消耗性能的原因：
       在第一次页面渲染完毕后(第一次渲染，必然会引发一次：Layout(重排)和Painting(重绘))
       + 当我们进行了 “调整了视口大小、调整某些节点的位置(或大小)、删除/新增某些节点...” 等操作，那么需要重新计算每个节点在视口中的最新位置，也就是重新Layout「被称之为：回流/重排 Reflow」
       + 在重排过后，必然会引发一次重绘！！
       + 而如果，只是修改节点的 “背景/文字颜色、透明度、transfrom...” 等，则只会引发重绘！
     操作DOM消耗性能，主要就体现在：回流/重排

-----------------
如何减少DOM的回流/重排？
  @1 读写分离
    当代浏览器都存在“渲染队列”机制!
    + 把获取元素样式和设置元素样式的代码分离开！
    + 批量设置CSS样式「设置样式类名、cssText」

  @2 新增元素要采用批量新增法
    + 字符串拼接
    + 文档碎片：存储节点的容器

  @3 修改元素样式，可能基于 transform「opacity...」 ，因为其不会导致DOM重排

  @4 需要修改样式的元素，尽可能脱离文档流，后期只让当前层重排或者重绘{虽然无法避免，但是损耗降低}！！

  ...

 */
/* let box = document.getElementById('box');
let frag = document.createDocumentFragment();
for (let i = 1; i <= 10; i++) {
    let span = document.createElement('span');
    span.innerHTML = i;
    span.style.cssText = `
            width:50px;
            height:50px;
            background:pink
        `;
    frag.appendChild(span);
}
box.appendChild(frag); */


/* let box = document.getElementById('box');
let str = ``;
for (let i = 1; i <= 10; i++) {
    str += `<span style="width:50px;height:50px;background:pink;">
        ${i}
    </span>`;
}
box.innerHTML = str; */

/*
// 触发十次回流
let box = document.getElementById('box');
for (let i = 1; i <= 10; i++) {
    let span = document.createElement('span');
    span.innerHTML = i;
    span.style.cssText = `
        width:50px;
        height:50px;
        background:pink
    `;
    box.appendChild(span);
}
*/


//------------------
/* let box = document.getElementById('box');
// 一次回流
box.style.cssText = `
    margin:0 auto;
    width:200px;
    height:200px;
    background:pink
`; */

/* // 两次次回流
box.style.margin = "0 auto";
box.style.width = '200px';
console.log(box.style.width);
box.style.height = '200px';
console.log(box.style.height);
box.style.background = 'pink'; */

/* // 一次回流
box.style.margin = "0 auto";
box.style.width = '200px';
box.style.height = '200px';
box.style.background = 'pink'; */








/* 
// 所有资源都加载完，触发这个事件
window.onload = function () {
    let box = document.getElementById('box');
    console.log(box);
}; 
*/

/* let box = document.getElementById('box');
console.log(box); */